package util;

import java.io.PrintStream;
import java.util.Set;
import java.util.HashSet;

/**
 * A static object used to provide general utility based on args supplied to {@link #init(String[])}.
 * This allows other classes to use these methods in a static-way without knowing about command line arguments.
 * @author Bitidork
 *
 */
public final class lib {
	// %%%%%%%%%%%%%%%%%%%%%%
	// Constants
	// %%%%%%%%%%%%%%%%%%%%%%
	
	public final static String FLAG_PREFIX = "-";
	
	// %%%%%%%%%%%%%%%%%%%%%%
	// Default flags
	// %%%%%%%%%%%%%%%%%%%%%%
	
	public final static String FLAG_DEBUG_GENERIC = FLAG_PREFIX + "debug_generic";
	
	public final static String FLAG_DEBUG_MSG_HANDLER = FLAG_PREFIX + "debug_msghandler";
	
	public final static String FLAG_DEBUG_RETRY_ERRORS = FLAG_PREFIX + "debug_retry";
	
	// %%%%%%%%%%%%%%%%%%%%%%
	// Util
	// %%%%%%%%%%%%%%%%%%%%%%
	
	/**
	 * Prints the debug string to the print stream if a supplied flag is present in the arguments to {@link #init(String[])}.
	 * @param ps The print stream.
	 * @param flags The flags to check for.
	 * @param dbg The debug string to print.
	 */
	public static void debug( final PrintStream ps, final String dbg, final String... flags ) {
		if ( ps == null ) {
			System.err.println("Null PrintStream object supplied to debug");
			return;
		}
		
		for ( String flag : flags ) {
			if ( lib.hasFlag( flag ) ) {
				ps.println( dbg );
				break;
			}
		}
	}
	
	/**
	 * Prints the debug string to standard out if a supplied flag is present in the arguments to {@link #init(String[])}.
	 * @param flags The flags to check for.
	 * @param dbg The debug string to print.
	 */
	public static void debug( final String dbg, final String... flags ) {
		lib.debug( System.out, dbg, flags );
	}
	
	/**
	 * Prints the debug string to standard out only if {@value #FLAG_DEBUG_GENERIC} is present as an argument supplied to {@link #init(String[])}.
	 * @param dbg The debug string to print.
	 */
	public static void debug( final String dbg ) {
		lib.debug( dbg, FLAG_DEBUG_GENERIC );
	}
	
	// %%%%%%%%%%%%%%%%%%%%%%
	// Constructors
	// %%%%%%%%%%%%%%%%%%%%%%
	
	/**
	 * Initializes settings based on the arguments supplied.
	 * A flag is any argument beginning with a {@value #FLAG_PREFIX} and not containing a "=".
	 * @param args The arguments.
	 */
	public static void init( final String[] args ) {
		lib.args = new HashSet<String>( );
		lib.flags = new HashSet<String>( );
		for ( String s : args ) {
			lib.args.add( s );
			
			// add to set of flags
			if ( s.startsWith(FLAG_PREFIX) && !s.contains("=") )
				lib.flags.add( s );
		}
	}
	
	// %%%%%%%%%%%%%%%%%%%%%%
	// Fields and accessors
	// %%%%%%%%%%%%%%%%%%%%%%
	
	/**
	 * A container used to determine the presence of an argument.
	 */
	private static Set<String> args = null;
	
	/**
	 * A container used to determine the presence of a flag.
	 * A flag is any argument beginning with a {@value #FLAG_PREFIX} and not containing a "=".
	 */
	private static Set<String> flags = null;
	
	/**
	 * Determines whether the string was in the arguments supplied to {@link #init(String[])}.
	 * @param s The string.
	 * @return Returns true if and only if the string was in the arguments supplied to {@link #init(String[])}.
	 */
	public static boolean hasArg( final String s ) {
		return args == null ? false : args.contains( s );
	}
	
	/**
	 * Determines whether the string was a flag supplied to {@link #init(String[])}.
	 * @param s The string.
	 * @return Returns true if and only if the string was a flag supplied to {@link #init(String[])}. A flag is any argument beginning with a {@value #FLAG_PREFIX} and not containing a "=".
	 */
	public static boolean hasFlag( final String s ) {
		return flags == null ? false : flags.contains( s );
	}
}
